use chrono::{DateTime as CDatetTime, Utc};
use serde::{Deserialize, Serialize};
use wither::{
    bson::{oid::ObjectId, DateTime},
    Model,
};

use crate::GLOBAL_CONFIG;
/// ## WechatInteractiveModel
/// 与微信交互需要用到的token等数据
/// 有的数据存在过期时间，建议开启一个后台任务来刷新
#[derive(Debug, Clone, Serialize, Deserialize, Model)]
pub struct WechatSettingModel {
    #[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
    pub id: Option<ObjectId>,
    pub access_token: Option<String>,
    pub access_expires_time: DateTime,
    pub jsapi_tocket: Option<String>,
    pub jsapi_expires_time: DateTime,
}
impl Default for WechatSettingModel {
    fn default() -> Self {
        let now = DateTime::now();
        Self {
            id: None,
            access_token: None,
            access_expires_time: now,
            jsapi_tocket: None,
            jsapi_expires_time: now,
        }
    }
}
/// ## WechatWebOAuthToken
#[derive(Debug, Clone, Serialize, Deserialize, Model)]
pub struct WechatWebOAuthToken {
    #[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
    pub id: Option<ObjectId>,
    pub user_id: Option<ObjectId>,
    pub created_at: DateTime,
    pub expired_time: DateTime,
}
impl Default for WechatWebOAuthToken {
    fn default() -> Self {
        let cfg_guard = GLOBAL_CONFIG
            .read()
            .unwrap()
            .as_ref()
            .map(|c| c.wechat.clone())
            .unwrap_or_default();
        let e = cfg_guard.web_token_expires;
        let current = Utc::now();
        let et = current + chrono::Duration::milliseconds(e);
        Self {
            id: None,
            user_id: None,
            created_at: DateTime::from_chrono(current),
            expired_time: DateTime::from_chrono(et),
        }
    }
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatWebOAuthTokenDTO {
    pub id: Option<String>,
    pub user_id: Option<String>,
    pub created_at: CDatetTime<Utc>,
    pub expired_time: CDatetTime<Utc>,
}

impl From<WechatWebOAuthToken> for WechatWebOAuthTokenDTO {
    fn from(t: WechatWebOAuthToken) -> Self {
        Self {
            id: t.id.map(|oid| oid.to_string()),
            user_id: t.user_id.map(|oid| oid.to_string()),
            created_at: t.created_at.to_chrono(),
            expired_time: t.expired_time.to_chrono(),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WechatUser {
    pub token: WechatWebOAuthToken,
}
